package com.example.mykotlin.base.util

import java.util.concurrent.TimeUnit
import org.redisson.api.RLock


/**
 * Redisson分布式锁工具类
 */
class RedissonUtil {
    companion object {
        private const val LOCK = "LOCK_"

        /**
         * 带超时的锁
         * @param lockKey
         * @param timeout 超时时间 单位：秒
         */
        fun lock(lockKey: String?, timeout: Long): RLock {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            lock.lock(timeout, TimeUnit.SECONDS)
            return lock
        }

        /**
         * 带超时的锁
         * @param lockKey
         * @param unit 时间单位
         * @param timeout 超时时间
         */
        fun lock(lockKey: String?, unit: TimeUnit?, timeout: Long): RLock {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            lock.lock(timeout, unit)
            return lock
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 最多等待时间
         * @param unit TimeUnit时间单位
         * @return
         */
        fun tryLock(lockKey: String?, waitTime: Long, unit: TimeUnit): Boolean {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            return try {
                lock.tryLock(waitTime, unit)
            } catch (e: InterruptedException) {
                false
            }
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 最多等待时间
         * @param leaseTime 上锁后自动释放锁时间
         * @return
         */
        fun tryLock(lockKey: String?, waitTime: Long, leaseTime: Long): Boolean {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            return try {
                lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)
            } catch (e: InterruptedException) {
                false
            }
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 最多等待时间,单位秒
         * @param leaseTime 上锁后自动释放锁时间,单位秒
         * @return
         */
        fun tryLockAndGetLock(lockKey: String?, waitTime: Long, leaseTime: Long): Pair<RLock, Boolean> {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            val flag = try {
                lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)
            } catch (e: InterruptedException) {
                false
            }
            return lock to flag
        }

        /**
         * 尝试获取锁
         * @param lockKey
         * @param unit 时间单位
         * @param waitTime 最多等待时间
         * @param leaseTime 上锁后自动释放锁时间
         * @return
         */
        fun tryLock(lockKey: String?, unit: TimeUnit?, waitTime: Long, leaseTime: Long): Boolean {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            return try {
                lock.tryLock(waitTime, leaseTime, unit)
            } catch (e: InterruptedException) {
                false
            }
        }

        /**
         * 释放锁
         * @param lockKey
         */
        fun unlock(lockKey: String?) {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            lock.unlock()
        }

        /**
         * 若没用锁情况下，就不调用释放锁的代码，若有锁情况下才调用释放锁
         * @param lockKey
         */
        fun unlockIgnore(lockKey: String?) {
            val lock: RLock = GetBean.redissonClient().getLock(LOCK + lockKey)
            if (!lock.isLocked) {
                return
            }
            lock.unlock()
        }

        /**
         * 释放锁
         * @param lock
         */
        fun unlock(lock: RLock) {
            lock.unlock()
        }
    }

}